﻿#region << 版 本 注 释 >>
/*
 * ========================================================================
 * Copyright(c) 北京天大天科科技发展有限公司, All Rights Reserved.
 * ========================================================================
 *  
 * 【当前类文件的功能】
 *  
 * CLR版本：4.0.30319.34014
 * 作者：杨朋飞  时间：2015/4/18 10:17:07
 * 文件名：EncryptHelper
 * 版本：V1.0.0
 * 
 * 修改者：           时间：               
 * 修改说明：
 * ========================================================================
*/
#endregion

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web.Security;

namespace YPF_CommonMethod
{
    /// <summary>
    /// 加密解密帮助类
    /// </summary>
    public static class EncryptHelper
    {
        /// <summary>
        /// 加密密钥
        /// </summary>
        public const string SKey = "ihlih*0037JOHT*)(PIJY*(()JI^)IO%";

        #region-------------------------Base64编码解码---------------------

        #region Base64实现编码

        /// <summary>
        /// Base64实现编码
        /// </summary>
        /// <param name="codeType">编码类型</param>
        /// <param name="code">待编码的字符串</param>
        /// <returns>返回编码后的字符串</returns>
        public static string Base64EncodeInfo(string codeType, string code)
        {
            string encode = "";
            byte[] bytes = Encoding.GetEncoding(codeType).GetBytes(code);
            try
            {
                encode = Convert.ToBase64String(bytes);
            }
            catch
            {
                encode = code;
            }
            return encode;
        }

        #endregion


        #region Base64实现解码

        /// <summary>
        ///  Base64实现解码
        /// </summary>
        /// <param name="codeType">编码类型</param>
        /// <param name="code">Base64编码后的字符串</param>
        /// <returns>返回解码后的字符串</returns>
        public static string Base64DecodeInfo(string codeType, string code)
        {
            string decode = "";
            byte[] bytes = Convert.FromBase64String(code);
            try
            {
                decode = Encoding.GetEncoding(codeType).GetString(bytes);
            }
            catch
            {
                decode = code;
            }
            return decode;
        }

        #endregion


        #endregion

        #region-------------------------Escape加密解密,处理全角字符有问题--

        /// <summary>
        /// Escape实现加密
        /// </summary>
        /// <param name="source">待加密的字符串</param>
        /// <returns>返回加密后的字符串</returns>
        public static string EscapeEncryptInfo(string source)
        {
            if (source == null)
            {
                return string.Empty;
            }
            StringBuilder stringBuilder = new StringBuilder();
            int length = source.Length;
            for (int i = 0; i < length; i++)
            {
                char chars = source[i];
                if (Char.IsLetterOrDigit(chars) || chars == '-' || chars == '_' || chars == '/' || chars == '\\' ||
                    chars == '.')
                {
                    stringBuilder.Append(chars);
                }
                else
                {
                    stringBuilder.Append(Uri.HexEscape(chars));
                }
            }
            return stringBuilder.ToString();
        }

        /// <summary>
        ///  Escape实现解密
        /// </summary>
        /// <param name="source">待解密的字符串</param>
        /// <returns>返回解密后的字符串</returns>
        public static string EscapeDecryptInfo(string source)
        {
            if (source == null)
            {
                return String.Empty;
            }
            StringBuilder stringBuilder = new StringBuilder();
            int length = source.Length;
            int i = 0;
            while (i != length)
            {
                stringBuilder.Append(Uri.IsHexEncoding(source, i) ? Uri.HexUnescape(source, ref i) : source[i++]);
            }
            return stringBuilder.ToString();
        }

        #endregion

        #region-------------------------倒序加1加密解密--------------------

        /// <summary>
        /// 倒序加1加密实现
        /// </summary>
        /// <param name="source">待加密的字符串</param>
        /// <returns>返回加密后的字符串</returns>
        public static string OrderEncryptStrInfo(string source)
        {
            byte[] bytes = new byte[source.Length];
            for (int i = 0; i <= source.Length - 1; i++)
            {
                bytes[i] = (byte)((byte)source[i] + 1);
            }
            source = "";
            for (int i = bytes.Length - 1; i >= 0; i--)
            {
                source += ((char)bytes[i]).ToString(CultureInfo.InvariantCulture);
            }
            return source;
        }

        /// <summary>
        /// 顺序减1解密实现
        /// </summary>
        /// <param name="source">待解密的字符串</param>
        /// <returns>返回解密后的字符串信息</returns>
        public static string OrderDecryptStrInfo(string source)
        {
            byte[] bytes = new byte[source.Length];
            for (int i = 0; i <= source.Length - 1; i++)
            {
                bytes[i] = (byte)((byte)source[i] - 1);
            }
            source = "";
            for (int i = bytes.Length - 1; i >= 0; i--)
            {
                source += ((char)bytes[i]).ToString(CultureInfo.InvariantCulture);
            }
            return source;
        }

        #endregion

        #region-------------------------MD5加密----------------------------

        /// <summary>
        /// 实现Md5加密算法，对传递进来的字符串进行加密然后可以获取加密后的内容（MD5CryptoServiceProvider）
        /// </summary>
        /// <param name="source">待加密的字符串</param>
        /// <returns>返回加密后的字符串信息</returns>
        public static string Md5EncryptInfo(string source)
        {
            MD5 md5 = new MD5CryptoServiceProvider(); //实例化MD5加密对象
            byte[] result = md5.ComputeHash(Encoding.Default.GetBytes(source));
            return Encoding.Default.GetString(result);
        }

        /// <summary>
        /// 实现Md5加密算法，对传递进来的字符串进行加密然后可以获取加密后的内容（HashPasswordForStoringInConfigFile）
        /// 方法调用：EncryptHelper.Md5EncryptInfo("字符串",EncryptHelper.SKey);
        /// </summary>
        /// <param name="source">待加密的字符串</param>
        /// <param name="sKey">加密密钥</param>
        /// <returns>返回加密后的字符串</returns>
        public static string Md5EncryptInfo(string source, string sKey)
        {
            string tempStr = FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5");
            //返回加密后统一转换成小写展示
            return FormsAuthentication.HashPasswordForStoringInConfigFile(source + tempStr, "md5").ToLower();
        }

        /// <summary>
        /// MD5加密_byTDTK
        /// </summary>
        /// <param name="text">待加密字符串</param>
        /// <returns></returns>
        public static string Md5Crypt(string text)
        {
            string strMD5Result = "";
            try
            {
                byte[] arryByte = Encoding.Default.GetBytes(text);	//转换为字节数组
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] arryHashByte = md5.ComputeHash(arryByte);			//加密为128位，16个字节
                strMD5Result = BitConverter.ToString(arryHashByte);
                strMD5Result = strMD5Result.Replace("-", String.Empty);				//除掉分隔符
            }
            catch (System.ArgumentNullException)
            {
                throw;
            }

            return strMD5Result;
        }

        #endregion

        #region-------------------------DES加密和解密----------------------

        /// <summary>
        /// Des实现加密
        /// </summary>
        /// <param name="source">待加密的字符串</param>
        /// <param name="sKey">加密密钥</param>
        /// <returns>返回加密后的字符串</returns>
        public static string DesEncryptInfo(string source, string sKey)
        {
            var desCrypto = new DESCryptoServiceProvider(); //初始化对象
            byte[] byteInputByteArray = Encoding.Default.GetBytes(source);

            desCrypto.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5")
                .Substring(0, 8))
            ;
            desCrypto.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5")
                .Substring(0, 8));
            var memoryStream = new MemoryStream();
            var cryptoStream = new CryptoStream(memoryStream, desCrypto.CreateEncryptor(), CryptoStreamMode.Write);
            //目标数据流转化为新实例
            cryptoStream.Write(byteInputByteArray, 0, byteInputByteArray.Length);
            cryptoStream.FlushFinalBlock();

            var stringBuilder = new StringBuilder();
            foreach (var memoryS in memoryStream.ToArray())
            {
                stringBuilder.AppendFormat("{0:X2}", memoryS);
            }
            return stringBuilder.ToString();
        }

        /// <summary>
        /// Des实现解密
        /// </summary>
        /// <param name="source">待解密的字符串信息</param>
        /// <param name="sKey">解密密钥</param>
        /// <returns>返回解密后的字符串</returns>
        public static string DesDecryptInfo(string source, string sKey)
        {
            var desCrypto = new DESCryptoServiceProvider(); //初始化对象
            int length = source.Length / 2;
            byte[] byteInputByteArray = new byte[length];

            //循环数据流
            int i;
            for (int x = 0; x < length; x++)
            {
                i = Convert.ToInt32(source.Substring(x * 2, 2), 16);
                byteInputByteArray[x] = (byte)i;
            }
            //组织返回解密后的字符串
            desCrypto.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5")
                .Substring(0, 8));
            desCrypto.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5")
                .Substring(0, 8));
            var memoryStream = new MemoryStream();
            var cryptoStream = new CryptoStream(memoryStream, desCrypto.CreateDecryptor(), CryptoStreamMode.Write);
            cryptoStream.Write(byteInputByteArray, 0, byteInputByteArray.Length);
            cryptoStream.FlushFinalBlock();
            return Encoding.Default.GetString(memoryStream.ToArray());
        }

        //默认密钥向量
        private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };

        /// <summary>
        /// DES加密字符串_byTDTK
        /// </summary>
        /// <param name="encryptString">待加密的字符串</param>
        /// <param name="encryptKey">加密密钥,要求为8位</param>
        /// <returns>加密成功返回加密后的字符串，失败返回源串</returns>
        public static string EncryptDes(string encryptString, string encryptKey)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
                byte[] rgbIv = Keys;
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIv), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Convert.ToBase64String(mStream.ToArray());
            }
            catch
            {
                return encryptString;
            }
        }

        /// <summary>
        /// DES解密字符串_byTDTK
        /// </summary>
        /// <param name="decryptString">待解密的字符串</param>
        /// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
        /// <returns>解密成功返回解密后的字符串，失败返源串</returns>
        public static string DecryptDes(string decryptString, string decryptKey)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
                byte[] rgbIv = Keys;
                byte[] inputByteArray = Convert.FromBase64String(decryptString);
                DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIv), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Encoding.UTF8.GetString(mStream.ToArray());
            }
            catch
            {
                return decryptString;
            }
        }

        #endregion


    }
}
